import java.io.*;
import java.util.*;

public class Main {

	
	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		
		if(args.length<3)
		{
			printHelp();
			return;
		}
		String escStr = args[1];
		String oName = args[2];
		String [] escs = escStr.split(",");
		File folder = new File(args[0]);
		Map<String, Vector<String>> map = new HashMap<String, Vector<String>>();
		
		
		Stack<File> s = new Stack<File>();
		for(File file:folder.listFiles())
		{
			s.push(file);
		}
		while(!s.isEmpty())
		{
			File file = s.pop();
			if(file.isFile())
			{
				if(file.getName().endsWith(".cpp") || file.getName().endsWith(".cc"))
				{
					//String name = file.getName().substring(0, file.getName().length()-4);
					String name = (genDiff(file,folder));
					Vector<String> vec = new Vector<String>();
					map.put(name, vec);
					Scanner sc = new Scanner(new FileInputStream(file));
					
					while(sc.hasNext())
					{
						String line = sc.nextLine().trim();
						if(line.startsWith("#include"))
						{
							String [] splitted = line.split("\"");
							if(splitted.length > 1)
							{
								String h = splitted[1];
								if(!startWith(escs, h))
								{
									String prefix =genDiff(file.getParentFile(),folder);
									if(prefix.length()==0)
										vec.add(h);
									else
										vec.add(genDiff(file.getParentFile(),folder)+"/"+h);
								}
							}
						}
							
					}
					sc.close();
				}
			}
			else // folder
			{
				if(contains(escs, file.getName()))
					continue;
				for(File iFile:file.listFiles())
					s.push(iFile);
			}
		}
		PrintWriter out = new PrintWriter(new FileOutputStream(new File(args[0]+"\\Makefile")));

		out.print("OBJS =");
		for(String obj:map.keySet())
			out.print(" "+trimSuffix(obj)+".o");
		out.println();
		
		out.println("CC = g++\n"+
			"DEBUG = -O2\n"+
			"CFLAGS = -Wall -c $(DEBUG)\n"+
			"LFLAGS = -Wall $(DEBUG)\n"
			);
		
		out.println(oName+" : $(OBJS)\n"+
					"\t$(CC) $(LFLAGS) $(OBJS) -o "+oName);
		
		for(String obj:map.keySet())
		{
			out.print(trimSuffix(obj)+".o");
			Vector<String> vec = map.get(obj);
			if(vec.size()>0)
			{
				out.print(" :");
				for(String str:vec)
					out.print(" "+str);
			}
			
			out.println("\n\t$(CC) $(CFLAGS) "+obj+" -o "+trimSuffix(obj)+".o");
		}
		out.close();
	}

	private static void printHelp() {
		System.out.println("Usage: java <executable_name> source_folder "+
							" exclude_folders output_name");
		System.out.println("Put the name of the folders to be excluded"
				+" in the exclude_folders parameter, separated by ','.");
	}

	private static String trimSuffix(String str) {
		String [] splitted = str.split("\\.");
		if(splitted.length == 1)
			return str;
		return str.substring(0, str.length() - splitted[splitted.length-1].length()-1);
		
	}

	private static String genDiff(File file, File folder) {
		if(file.getAbsolutePath().length() <= folder.getAbsolutePath().length())
			return "";
		return toUnix(file.getAbsolutePath().substring(folder.getAbsolutePath().length()+1));
	}

	private static String toUnix(String str) {
		return str.replace('\\', '/');
	}

	private static boolean startWith(String[] escs, String h) {
		String [] splitted = h.split("\\/");
		if(splitted.length <= 1)
			return false;
		for(String str:escs)
		{
			for(int i=0; i<splitted.length-1; i++)
				if(str.equals(splitted[i]))
					return true;
		}
		return false;
	}

	private static boolean contains(String[] escs, String name) {
		for(String str:escs)
			if(str.equals(name))
				return true;
		return false;
	}

}
